﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MSBTC.Model;

namespace MSBTC.WinForms
{
    public partial class AssignEquipForm : Form
    {
        PMSContext dbcontext = new PMSContext();
        Equipment dbeqp = new Equipment();
        ProjEquip dbpjeq = new ProjEquip();
        private int[] numitemselcted = new int[1000];
        private string[] itemselected = new string[1000];
        private string[] retequip = new string[1000];
        private int[] qtyret = new int[1000];

        public AssignEquipForm()
        {
            InitializeComponent();
        }

        private void AssignEquipForm_Load(object sender, EventArgs e)
        {
            cmbPName.SelectedIndex = 0;
            txtqty.Enabled = false;
            lbEquip.Enabled = false;
            lblsct.Enabled = false;
            btnfront.Enabled = false;
            btnBack.Enabled = false;
            btnSave.Enabled = false;

            Array.Clear(numitemselcted, 0, numitemselcted.Length);
            Array.Clear(itemselected, 0, itemselected.Length);
            Array.Clear(retequip, 0, retequip.Length);
            Array.Clear(qtyret, 0, qtyret.Length);

            var name = (from p in dbcontext.Projects
                        select p).ToList();
            if (name != null)
            {
                foreach (var pn in name)
                {
                    cmbPName.Items.Add(pn.Project_Name);
                }
            }
            else
            {     
                MessageBox.Show("There are no Projects listed, please add new projects in main menu.", "Data Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                cmbPName.SelectedIndex = 0;
                this.Hide();  
            }

            var eqmt = (from eq in dbcontext.Equipments
                        where eq.Quantity - eq.QtyUsed != 0
                        select eq).ToList();
            if (eqmt != null)
            {
                foreach (var eqp in eqmt)
                {
                    lbEquip.Items.Add(eqp.Equip_Name);
                }
            }
            else
            {
                MessageBox.Show("There are no equipments stored, please add equipments in main menu", "Data Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Hide();
            }
        }

        private void cmbPName_SelectedIndexChanged(object sender, EventArgs e)
        {
            lblsct.Items.Clear();
            lblQty.Text = "";
            txtqty.Clear();
            lblused.Text = "";
            lbltrans.Text = "";
            if (cmbPName.SelectedIndex != 0)
            {
                Array.Clear(numitemselcted, 0, numitemselcted.Length);
                Array.Clear(itemselected, 0, itemselected.Length);
                Array.Clear(retequip, 0, retequip.Length);
                Array.Clear(qtyret, 0, qtyret.Length);

                lbEquip.Enabled = true;
                lblsct.Enabled = true;
                btnfront.Enabled = true;
                btnBack.Enabled = true;
                btnSave.Enabled = true;

                var prj = (from eq in dbcontext.Projects
                           where eq.Project_Name == cmbPName.SelectedItem
                           select eq).SingleOrDefault();
                if (prj != null)
                {
                    var prjeq = (from pe in dbcontext.PrjEqs
                                 where pe.Projectid_FK == prj.Projectid_PK
                                 select pe).ToList();
                    if (prjeq != null)
                    {
                        foreach (var peq in prjeq)
                        {
                            var eqmt = dbcontext.Equipments.Find(peq.Equipid_FK);
                            lblsct.Items.Add(eqmt.Equip_Name);
                        }
                    }
                }
            }
        }

        private void lbEquip_SelectedIndexChanged(object sender, EventArgs e)
        {
            btnBack.Enabled = false;
            btnfront.Enabled = true;
            
            if (lblsct.SelectedIndex != -1)
            {
                lblsct.ClearSelected();
                //lblsct.SelectedIndex = 0;
               
            }
            if (lbEquip.SelectedItems.Count != 0)
            {
                txtqty.Enabled = true;
                string itmslt = lbEquip.SelectedItem.ToString();
                var eq = (from eqp in dbcontext.Equipments
                          where eqp.Equip_Name == itmslt
                          select eqp).SingleOrDefault();
                if (eq != null)
                {
                    lblQty.Text = Convert.ToString(eq.Quantity - eq.QtyUsed);
                    lblused.Text = eq.QtyUsed.ToString();
                }

                int indx = Array.IndexOf(itemselected, itmslt);
                if (indx != -1)
                {
                    lbltrans.Text = numitemselcted[indx].ToString();
                }
                else
                {
                    lbltrans.Text = "0";
                }
            }
            else
            {
                lblsct.SelectedItem = -1;
                txtqty.Enabled = false;
            }
        }

        private void lblsct_SelectedIndexChanged(object sender, EventArgs e)
        {
            lblQty.Text = "";
            btnfront.Enabled = false;
            btnBack.Enabled = true;
                                    
            if (lbEquip.SelectedIndex != -1)
            {
                lbEquip.ClearSelected();
                    //lbEquip.SelectedIndex = 0;
            }
            if (lblsct.SelectedItems.Count != 0)
            {
                txtqty.Enabled = true;
                string itmslt = lblsct.SelectedItem.ToString();
                List<string> itmlst = new List<string>(retequip);
                List<int> qtylst = new List<int>(numitemselcted);

                var proj = (from p in dbcontext.Projects
                            where p.Project_Name == cmbPName.SelectedItem
                            select p).SingleOrDefault();

                var eq = (from eqp in dbcontext.Equipments
                          where eqp.Equip_Name == itmslt
                          select eqp).SingleOrDefault();
                if (eq != null)
                {
                    var preq = (from pj in dbcontext.PrjEqs
                                where pj.Equipid_FK == eq.Equipmentid_PK
                                && pj.Projectid_FK == proj.Projectid_PK
                                select pj).SingleOrDefault();

                    int qtynum = Array.IndexOf(retequip, itmslt);
                    if (qtynum != -1)
                    {
                        int addqty = qtyret[qtynum];
                        lblused.Text = preq.QuantityUsed.ToString();
                        lblQty.Text = eq.Quantity.ToString();
                        lbltrans.Text = addqty.ToString();
                    }
                    else
                    {
                        lblQty.Text = Convert.ToString((eq.Quantity - eq.QtyUsed));
                        lblused.Text = preq.QuantityUsed.ToString();
                    }
                }
                int indx = Array.IndexOf(retequip, itmslt);
                if (indx != -1)
                {
                    lbltrans.Text = qtyret[indx].ToString();
                }
                else
                {
                    lbltrans.Text = "0";
                }
            }
            else
            {
                lbEquip.SelectedItem = -1;
                txtqty.Enabled = false;
            }
        }

        private void txtqty_TextChanged(object sender, EventArgs e)
        {
            FormHelpers help = new FormHelpers();
            //check every letters
            if (txtqty.Text != "")
            {
                if (help.SpecChar(txtqty.Text, txtqty) == false || (System.Text.RegularExpressions.Regex.IsMatch(txtqty.Text, "[^0-9]") == true))
                {
                    MessageBox.Show("Only Numeric values are allowed", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txtqty.Clear();
                    return;
                }                    
            }
        }

        private void btnfront_Click(object sender, EventArgs e)
        {
            if (txtqty.Text != "")
            {
                if (Convert.ToInt32(txtqty.Text) <= Convert.ToInt32(lblQty.Text) || Convert.ToInt32(txtqty.Text) > 0)
                {
                    if (lbEquip.SelectedIndex != -1)
                    {
                        string slctd = lbEquip.SelectedItem.ToString();
                        int qty = Convert.ToInt32(txtqty.Text);
                        int cnt = 0;
                        if (lblsct.Items.Count != 0)
                        {
                            foreach (var item in lblsct.Items)
                            {
                                if (slctd == item)//if the selected item and item in lblsct is the same
                                {
                                    //retrieve equipment to be removed in lbequip
                                    var eqp = (from eq in dbcontext.Equipments
                                               where eq.Equip_Name == slctd //&& qty <= eq.Quantity - eq.QtyUsed
                                               select eq).SingleOrDefault();
                                    if (eqp != null)
                                    {
                                        //if quantity inputted was equal to the difference of 2 quantities
                                        if (qty == eqp.Quantity - eqp.QtyUsed)
                                        { //remove the item
                                            lbEquip.Items.Remove(slctd);
                                            break;
                                        }
                                    }
                                }//else check if not equal to selected equipname and does not contains with the same equipname
                                else if (slctd != item && lblsct.Items.Contains(slctd) == false)
                                {
                                    var eqp = (from eq in dbcontext.Equipments
                                               where eq.Equip_Name == slctd //&& qty <= eq.Quantity - eq.QtyUsed
                                               select eq).SingleOrDefault();
                                    if (eqp != null)
                                    {
                                        //if quantity inputted was equal to the difference of 2 quantities
                                        if (qty == eqp.Quantity - eqp.QtyUsed)
                                        {
                                            lbEquip.Items.Remove(slctd);
                                        }
                                        lblsct.Items.Add(slctd);
                                        break;
                                    }
                                }
                            }
                            //store to an array for saving
                            List<string> itmlst = new List<string>(itemselected);
                            foreach (var arrlst in itmlst)
                            {//get all values stored in the itemselected
                                if (arrlst != null)
                                {
                                    cnt += 1;
                                }
                                else
                                {
                                    if (cnt > 0)
                                    {
                                        break;
                                    }
                                    else
                                    {
                                        cnt -= 1;
                                        break;
                                    }

                                }
                            }
                            //set the array value where to store
                            itemselected[cnt + 1] = slctd;
                            numitemselcted[cnt + 1] = qty;
                            lbltrans.Text = qty.ToString();
                            txtqty.Clear();
                        }
                        else//if lbsct is not null or equal 0
                        {
                            var eqp = (from eq in dbcontext.Equipments
                                       where eq.Equip_Name == slctd //&& qty <= eq.Quantity - eq.QtyUsed
                                       select eq).SingleOrDefault();
                            if (eqp != null)
                            {
                                lblsct.Items.Add(slctd); 
                            }
                            List<string> itmlst = new List<string>(itemselected);
                            foreach (var arrlst in itmlst)
                            {
                                if (arrlst != null)
                                {
                                    cnt += 1;
                                }
                                else
                                {
                                    if (cnt > 0)
                                    {
                                        break;
                                    }
                                    else
                                    {
                                        cnt -= 1;
                                        break;
                                    }

                                }
                            }
                            itemselected[cnt + 1] = slctd;
                            numitemselcted[cnt + 1] = qty;
                            txtqty.Clear();
                        }

                    }
                    else
                    {
                        MessageBox.Show("Please check the Quantity if not less than 0 or greater than the remaining quantity", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }
                else
                {
                    MessageBox.Show("Please enter quantity to be transfer", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
          }

        private void btnBack_Click(object sender, EventArgs e)
        {
            if (txtqty.Text != "")
            {
                if (Convert.ToInt32(txtqty.Text) <= Convert.ToInt32(lblused.Text) || Convert.ToInt32(txtqty.Text) > 0)
                {
                    if (lblsct.SelectedIndex != -1)
                    {
                        string itemslt = lblsct.SelectedItem.ToString();
                        int qtyno = Convert.ToInt32(txtqty.Text);
                        List<string> itmlst = new List<string>(itemselected);
                        List<int> qtylst = new List<int>(numitemselcted);
                        List<string> reteqp = new List<string>(retequip);
                        List<int> retqtyno = new List<int>(qtyret);


                        foreach (var item in lbEquip.Items)
                        {
                            if (itemslt == item)//if the selected item and item in lblsct is the same
                            {
                                //retrieve equipment to be removed in lblsct
                                var eqp = (from eq in dbcontext.Equipments
                                           where eq.Equip_Name == itemslt && qtyno <= eq.Quantity - eq.QtyUsed
                                           select eq).SingleOrDefault();
                                if (eqp != null)
                                {
                                    //if quantity inputted was equal to the difference of 2 quantities
                                    if (qtyno == eqp.Quantity - eqp.QtyUsed)
                                    { //remove the item
                                        lblsct.Items.Remove(itemslt);
                                        break;
                                    }
                                }
                            }//else check if not equal to selected equipname and does not contains with the same equipname
                            else if (itemslt != item && lbEquip.Items.Contains(itemslt) == false)
                            {
                                var eqp = (from eq in dbcontext.Equipments
                                           where eq.Equip_Name == itemslt && qtyno <= eq.Quantity - eq.QtyUsed
                                           select eq).SingleOrDefault();
                                if (eqp != null)
                                {
                                    //if quantity inputted was equal to the difference of 2 quantities
                                    if (qtyno == eqp.Quantity - eqp.QtyUsed)
                                    {
                                        lblsct.Items.Remove(itemslt);
                                    }
                                    lbEquip.Items.Add(itemslt);
                                    break;
                                }
                            }
                        }

                        //remove same identity
                        foreach (var arrlst in itmlst)
                        {//get all values stored in the itemselected then remove with the same values
                            if (arrlst != null)
                            {
                                if (arrlst == itemslt)
                                {
                                    int indxno = Array.IndexOf(itemselected, arrlst);
                                    int qytno = numitemselcted[indxno];
                                    itmlst.RemoveAt(indxno);
                                    if (qytno > Convert.ToInt32(txtqty.Text))
                                    {
                                        int cnt = 0;
                                        foreach (var retarr in retequip)
                                        {
                                            if (retarr != null)
                                            {
                                                cnt += 1;
                                            }
                                            else
                                            {
                                                if (cnt > 0)
                                                {
                                                    break;
                                                }
                                                else
                                                {
                                                    cnt -= 1;
                                                    break;
                                                }
                                            }
                                        }
                                        //set the array value where to store
                                        retequip[cnt + 1] = itemslt;
                                        qtyret[cnt + 1] = qtyno - Convert.ToInt32(txtqty.Text);
                                    }
                                    qtylst.RemoveAt(indxno);
                                    break;
                                }
                            }
                            else
                            {
                                int cntr = 0;
                                foreach (var retarr in retequip)
                                {
                                    if (retarr != null)
                                    {
                                        cntr += 1;
                                    }
                                    else
                                    {
                                        if (cntr > 0)
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            cntr -= 1;
                                            break;
                                        }
                                    }
                                }
                                retequip[cntr + 1] = itemslt;
                                qtyret[cntr + 1] = Convert.ToInt32(txtqty.Text);
                                break;
                            }
                        }
                        lbltrans.Text = txtqty.Text;
                        txtqty.Clear();
                    }
                }
                else
                {
                    MessageBox.Show("Please check the Quantity if not less than 0 or greater than the quantity used", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
            else
            {
                MessageBox.Show("Please enter quantity to be transfer", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            List<string> reteqp = new List<string>(retequip);
            List<int> retqtyno = new List<int>(qtyret);
            int ctr = 0;

            try
            {
                foreach (var lstitm in itemselected)
                {
                    if (lstitm != null)
                    {
                        ctr += 1;
                        int eqindx = Array.IndexOf(itemselected, lstitm);
                        int qtyadd = numitemselcted[eqindx];

                        //check for existing equipment for data gathering
                        var eqp = (from eq in dbcontext.Equipments
                                   where eq.Equip_Name == lstitm
                                   select eq).SingleOrDefault();
                        if (eqp != null)
                        {//check for existing project name for data
                            var pj = (from p in dbcontext.Projects
                                      where p.Project_Name == cmbPName.SelectedItem
                                      select p).SingleOrDefault();
                            if (pj != null)
                            {
                                //check for existing equipment in project-equipment
                                var pjeq = (from peq in dbcontext.PrjEqs
                                            where peq.Equipid_FK == eqp.Equipmentid_PK && peq.Projectid_FK == pj.Projectid_PK
                                            select peq).SingleOrDefault();
                                if (pjeq == null)
                                {
                                    //save new record in project-equipment table
                                    dbpjeq.Projectid_FK = pj.Projectid_PK;
                                    dbpjeq.Equipid_FK = eqp.Equipmentid_PK;
                                    dbpjeq.QuantityUsed = qtyadd;
                                    dbcontext.Entry(dbpjeq).State = EntityState.Added;

                                    eqp.QtyUsed += qtyadd;
                                    dbcontext.Entry(eqp).State = EntityState.Modified;

                                    dbcontext.SaveChanges();

                                    //check all items in retequip array to minus all quantity with the same equipname then save to database
                                    foreach (var itmlist in retequip)
                                    {
                                        if (itmlist != null)
                                        {
                                            try
                                            {
                                                var checkitm = (from eq in dbcontext.Equipments
                                                                where eq.Equip_Name == itmlist
                                                                select eq).SingleOrDefault();
                                                if (checkitm != null)
                                                {
                                                    int qtyindex = Array.IndexOf(retequip, itmlist);
                                                    int quantityno = qtyret[qtyindex];

                                                    checkitm.QtyUsed -= quantityno;
                                                    dbcontext.Entry(checkitm).State = EntityState.Modified;

                                                    var prjequips = (from pjt in dbcontext.PrjEqs
                                                                     where pjt.Projectid_FK == pj.Projectid_PK &&
                                                                     pjt.Equipid_FK == checkitm.Equipmentid_PK
                                                                     select pjt).SingleOrDefault();
                                                    if (prjequips != null)
                                                    {
                                                        prjequips.QuantityUsed -= quantityno;
                                                        dbcontext.Entry(prjequips).State = EntityState.Modified;
                                                    }

                                                    dbcontext.SaveChanges();
                                                }
                                            }
                                            catch (Exception exc)
                                            {
                                                MessageBox.Show(exc.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                                return;
                                            }
                                        }
                                    }
                                }

                                else
                                {
                                    //save the modified quantity used in the a particular project
                                    pjeq.QuantityUsed += qtyadd;
                                    dbcontext.Entry(pjeq).State = EntityState.Modified;

                                    eqp.QtyUsed += qtyadd;
                                    dbcontext.Entry(eqp).State = EntityState.Modified;

                                    dbcontext.SaveChanges();

                                    int retitmlst = Array.IndexOf(retequip, eqp.Equip_Name);
                                    if (retitmlst != -1)
                                    {
                                        int quantityret = qtyret[retitmlst];
                                        eqp.QtyUsed -= quantityret;
                                        dbcontext.Entry(eqp).State = EntityState.Modified;

                                        pjeq.QuantityUsed -= quantityret;
                                        dbcontext.Entry(pjeq).State = EntityState.Modified;

                                        dbcontext.SaveChanges();

                                    }
                                    //else
                                    //{
                                    //    var prjeq = (from pje in dbcontext.PrjEqs
                                    //                 where pje.Projectid_FK == pj.Projectid_PK && pje.Equipid_FK == eqp.Equipmentid_PK
                                    //                 select pje).SingleOrDefault();

                                    //    prjeq.QuantityUsed -= qtyadd;
                                    //    dbcontext.Entry(prjeq).State = EntityState.Modified;

                                    //    pjeq.QuantityUsed += qtyadd;
                                    //    dbcontext.Entry(pjeq).State = EntityState.Modified;

                                    //    dbcontext.SaveChanges();
                                    //}
                                }
                            }
                        } 
                    }
                    else if (retequip != null)
                    {
                        try
                        {
                            foreach (var itmlist in retequip)
                            {
                                if (itmlist != null)
                                {

                                    var pj = (from p in dbcontext.Projects
                                              where p.Project_Name == cmbPName.SelectedItem
                                              select p).SingleOrDefault();
                                    if (pj != null)
                                    {
                                        var checkitm = (from eq in dbcontext.Equipments
                                                        where eq.Equip_Name == itmlist
                                                        select eq).SingleOrDefault();
                                        if (checkitm != null)
                                        {
                                            int qtyindex = Array.IndexOf(retequip, itmlist);
                                            int quantityno = qtyret[qtyindex];

                                            checkitm.QtyUsed -= quantityno;
                                            dbcontext.Entry(checkitm).State = EntityState.Modified;
                                            dbcontext.SaveChanges();

                                            var pjmats = (from pjt in dbcontext.PrjEqs
                                                          where pjt.Projectid_FK == pj.Projectid_PK &&
                                                          pjt.Equipid_FK == checkitm.Equipmentid_PK
                                                          select pjt).SingleOrDefault();
                                            if (pjmats != null)
                                            {
                                                pjmats.QuantityUsed -= quantityno;
                                                dbcontext.Entry(pjmats).State = EntityState.Modified;
                                                dbcontext.SaveChanges();
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    Array.Clear(retequip, 0, retequip.Length);
                                    Array.Clear(qtyret, 0, qtyret.Length);
                                    break;
                                }
                            }
                        }
                        catch (Exception exc)
                        {
                            MessageBox.Show(exc.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return;
                        }
                    }
                    else if (lstitm == null && ctr == 0)
                    {
                        //create code for back button to save data... RUSH!!!!
                        MessageBox.Show("There's no record to save", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    else
                    {
                        break;
                    }
                }
                MessageBox.Show("Successfully saved", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information);
                Array.Clear(numitemselcted, 0, numitemselcted.Length);
                Array.Clear(itemselected, 0, itemselected.Length);
                Array.Clear(retequip, 0, retequip.Length);
                Array.Clear(qtyret, 0, qtyret.Length);
                lbltrans.Text = "";
                Refresh();
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }   
    }
}
